// 加密实现，用于RuoYi框架的前端加密
// 加密实现，用于RuoYi框架的前端加密
// 使用JSEncrypt库进行RSA加密，使用CryptoJS库进行AES加密

// 导入JSEncrypt库
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min.js';
// 导入CryptoJS库
import CryptoJS from 'crypto-js';

// RSA公钥（需要与后端配置的公钥一致）
// 使用ruoyi-ui/.env中定义的VITE_APP_RSA_PUBLIC_KEY
// 注意：这里去掉了.env文件中的单引号
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ==';

/**
 * 生成随机密钥（16位）
 * @returns {string} 16位随机字符串
 */
export function generateRandomKey() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let key = '';
  for (let i = 0; i < 16; i++) {
    key += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return key;
}

/**
 * Base64编码
 * @param {string} str - 待编码字符串
 * @returns {string} Base64编码后的字符串
 */
export function encryptBase64(str) {
  return btoa(unescape(encodeURIComponent(String(str))));
}

/**
 * Base64解码
 * @param {string} str - 待解码的Base64字符串
 * @returns {string} 解码后的字符串
 */
export function decryptBase64(str) {
  try {
    return decodeURIComponent(escape(atob(str)));
  } catch (e) {
    console.error('Base64解码失败:', e);
    return str;
  }
}

/**
 * AES加密（使用CryptoJS库）
 * @param {string} message - 待加密数据
 * @param {string} aesKey - AES密钥
 * @returns {string} 加密后的字符串
 */
export function encryptWithAes(message, aesKey) {
  try {
    console.log('开始AES加密，原文类型:', typeof message);
    console.log('AES密钥:', aesKey, '密钥长度:', aesKey.length);
    
    // 确保消息是字符串
    const dataStr = typeof message === 'object' ? JSON.stringify(message) : String(message);
    console.log('AES加密前数据:', dataStr);
    
    // 将字符串密钥转换为CryptoJS格式
    const key = CryptoJS.enc.Utf8.parse(aesKey);
    console.log('AES密钥(CryptoJS格式):', key.toString());
    
    // 使用AES ECB模式加密，与Hutool的SecureUtil.aes默认配置保持一致
    // Hutool的SecureUtil.aes默认使用ECB模式和PKCS#7填充
    const encrypted = CryptoJS.AES.encrypt(dataStr, key, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
      // 显式设置没有IV，因为ECB模式不需要IV
      iv: undefined
    });
    
    // 获取加密结果的Base64字符串
    const encryptedStr = encrypted.toString();
    console.log('AES加密结果:', encryptedStr);
    
    return encryptedStr;
  } catch (error) {
    console.error('AES加密异常:', error);
    // 异常时返回原文，确保请求能继续进行
    return message;
  }
}

/**
 * AES解密（使用CryptoJS库）
 * @param {string} message - 待解密数据
 * @param {string} aesKey - AES密钥
 * @returns {string} 解密后的字符串
 */
export function decryptWithAes(message, aesKey) {
  try {
    // 将字符串密钥转换为CryptoJS格式
    const key = CryptoJS.enc.Utf8.parse(aesKey);
    // 使用AES ECB模式解密
    const decrypted = CryptoJS.AES.decrypt(message, key, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7
    });
    return decrypted.toString(CryptoJS.enc.Utf8);
  } catch (error) {
    console.error('AES解密异常:', error);
    return message;
  }
}

/**
 * RSA加密（使用JSEncrypt库）
 * @param {string} txt - 待加密文本
 * @returns {string} 加密后的字符串
 */
export function encrypt(txt) {
  try {
    console.log('开始RSA加密，原文:', txt);
    
    // 创建JSEncrypt实例
    const encryptor = new JSEncrypt();
    
    // 显式设置加密长度，确保与后端1024位RSA密钥兼容
    encryptor.keySize = 1024;
    
    // 尝试设置公钥
    console.log('尝试设置RSA公钥...');
    const keySet = encryptor.setPublicKey(publicKey);
    console.log('设置公钥结果:', keySet);
    
    // 检查密钥是否成功设置
    if (!encryptor.getPublicKey()) {
      console.error('公钥设置失败，无法获取公钥');
      // 尝试使用不包含PEM头部尾部的原始密钥格式
      const rawPublicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/y3CCJu868ghCG5dUj8wZK++RNlTLcXoMmdZWEQ/u02RgD5LyLAXGjLOjbMtC+/J9qofpSGTKSx/MCAwEAAQ==';
      console.log('尝试使用原始格式公钥:', rawPublicKey);
      encryptor.setPublicKey(rawPublicKey);
    }
    
    // 对数据进行加密
    console.log('执行RSA加密...');
    const encrypted = encryptor.encrypt(txt);
    
    console.log('RSA加密结果:', encrypted);
    
    if (!encrypted) {
      console.error('RSA加密失败，返回null');
      // 尝试使用替代方案：直接返回Base64编码的AES密钥（仅用于调试）
      console.warn('使用降级方案：直接返回Base64编码的AES密钥');
      return txt;
    }
    
    return encrypted;
  } catch (error) {
    console.error('RSA加密异常:', error);
    // 异常时返回原文，确保请求能继续进行
    return txt;
  }
}

/**
 * RSA解密（使用JSEncrypt库）
 * @param {string} txt - 待解密文本
 * @returns {string} 解密后的字符串
 */
export function decrypt(txt) {
  try {
    const encryptor = new JSEncrypt();
    // 前端不建议存放私钥，这里只提供解密接口但不实现
    console.warn('前端RSA解密功能不建议使用');
    return txt;
  } catch (error) {
    console.error('RSA解密异常:', error);
    return txt;
  }
}